package com.spring.boot.utils;

import cn.hutool.core.util.StrUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.spring.boot.entity.*;
import com.spring.boot.service.DangerLevelService;
import com.spring.boot.service.SummaryService;
import org.jsoup.select.Collector;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.*;
import java.util.logging.Logger;
import java.util.stream.Collectors;

import static com.spring.boot.utils.MyUtils.*;

@Component
public class Calculate {
//    /**
//     * SEIR 模型
//     *
//     * @return
//     */
//    public Map seri(Double s0, Double e0, Double i0, Double r0,
//                    Double r1, Double b1, Double r2, Double b2,
//                    Double a, Double y, Double N,
//                    Integer startDate, Integer endDate
//    ) {
//
//
//        Integer range = endDate - startDate;//预测日期范围
//        List<Double> S = new ArrayList<>(range);
//        List<Double> E = new ArrayList<>(range);
//        List<Double> I = new ArrayList<>(range);
//        List<Double> R = new ArrayList<>(range);
//        S.add(s0);
//        E.add(e0);
//        I.add(i0);
//        R.add(r0);
//        for (int i = 1; i < range; i++) {
//            Double tempS = S.get(i - 1) - r1 * b1 * S.get(i - 1) * I.get(i - 1) / N - r2 * b2 * S.get(i - 1) * E.get(i - 1) / N;
//            Double tempE = E.get(i - 1) + r1 * b1 * S.get(i - 1) * I.get(i - 1) / N - a * E.get(i - 1) + r2 * b2 * S.get(i - 1) * E.get(i - 1) / N;
//            Double tempI = I.get(i - 1) + ((a * E.get(i - 1)) - (y * I.get(i - 1)));
//            Double tempR = R.get(i - 1) + y * I.get(i - 1);
//            S.add(tempS);
//            E.add(tempE);
//            I.add(tempI);
//            R.add(tempR);
//
//        }
//
//        HashMap<String, List<Double>> map = new HashMap<>();
//        map.put("S", S);
//        map.put("E", E);
//        map.put("I", I);
//        map.put("R", R);
//        return map;
//    }

    @Autowired
    private DangerLevelService dangerLevelService;
    @Autowired
    private SummaryService summaryService;

    Integer plusDay = 0;//todo 如果时间循环到极限了怎么办？可以先查数据库里的最时间极限

    //    Integer plusDay2 = 0;
    @Scheduled(initialDelay = 3000, fixedDelay = 3000)
    public void calculateDangerLevel() {
        String newDate = MyUtils.getBeforeDays(getToday(), plusDay);
        HashMap<String, BigDecimal> map = new HashMap<>();
        //查询福建省每个城市昨天的迁入城市、和每个城市的迁入指数
        for (CityId item : CityId.values()) {
            String cityName = item.getCityName();
            //获取迁入城市
            List<InOutNum> moveInCities = MyUtils.getMoveInCities(cityName, getBeforeDays(newDate, -1));
            //获取迁入指数
            InOutNumCurve curve = MyUtils.getMoveInNum(cityName, getBeforeDays(newDate, -1));
            BigDecimal tempResult = new BigDecimal(0);
            //查询这些迁入城市的最新疫情数据
            for (InOutNum moveInCity : moveInCities) {
                ChinaCity cityInfo = getCityInfo(moveInCity.getCityName(), getBeforeDays(newDate, -1), 0);//todo 感觉关于时间的条件总有点问题
                tempResult = getDangerLevel(curve, tempResult, moveInCity, cityInfo);
            }
            map.put(cityName, tempResult);
        }
        DangerLevel dangerLevel = new DangerLevel(map.get("福州"), map.get("厦门"), map.get("莆田")
                , map.get("三明"), map.get("泉州"), map.get("漳州")
                , map.get("南平"), map.get("龙岩"), map.get("宁德"),
                newDate
        );
        dangerLevelService.saveOrUpdate(dangerLevel);
        plusDay -= 1;
    }

    private BigDecimal getDangerLevel(InOutNumCurve curve, BigDecimal tempResult, InOutNum moveInCity, ChinaCity cityInfo) {
        if (!cityInfo.getMark().equals("error")) {
            //todo 这里获取AsymptomaticRelative会出现值为“”的情况，这里是直接从数据库改换成0，暂时！！
            BigDecimal asy = new BigDecimal(cityInfo.getAsymptomaticRelative());//新增无症状
            BigDecimal curConfirm = new BigDecimal(cityInfo.getCurConfirm());//现有确诊
            BigDecimal add = asy.add(curConfirm);
            tempResult = tempResult.add(curve.getValue().multiply(moveInCity.getValue()).multiply(add));
//            tempResult = tempResult.add(curve.getValue().multiply(moveInCity.getValue()).multiply(curConfirm));
//            curve.getValue() * moveInCity.getValue() * (city.getAsymptomatic() + city.getCurConfirm())
        }
        return tempResult;
    }

    @Scheduled(initialDelay = 3000, fixedDelay = 3000)//启动就开始更新
    private void saveSummary() {
//        String newDate = MyUtils.getBeforeDays(getToday(), plusDay2);
        //计算并保存分析总结
//        List<Summary> summaries = summaryService.buildSummary(newDate);
        List<Summary> summaries = summaryService.buildSummary(MyUtils.today());
        summaryService.saveOrUpdateBatch(summaries);
//        plusDay2 -= 1;
    }
}
